package org.shuma.user.mng.service.impl;

import com.alipay.sofa.runtime.api.annotation.SofaReference;
import com.alipay.sofa.runtime.api.annotation.SofaReferenceBinding;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import org.shuma.email.facade.SendMessage;
import org.shuma.user.mng.constant.RegularConstant;
import org.shuma.user.mng.domain.entity.User;
import org.shuma.user.mng.domain.vo.AuthVo;
import org.shuma.user.mng.mapper.UserMapper;
import org.shuma.user.mng.service.AuthService;
import org.shuma.user.mng.utils.BcryptUtil;
import org.shuma.user.mng.utils.BeanCopyUtils;
import org.shuma.user.mng.utils.RedisUtil;
import org.shuma.user.utils.HttpCodeEnum;
import org.shuma.user.utils.Result;
import org.shuma.user.vo.UserVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.Objects;
import java.util.Random;
import java.util.UUID;

/**
 * @author zhao haitao
 * @date 2024/06/17 1:21 AM
 */
@Service
public class AuthServiceImpl implements AuthService {
    @SofaReference(interfaceType = SendMessage.class, uniqueId = "${service.email.unique.id}",
            binding = @SofaReferenceBinding(bindingType = "bolt"))
    private SendMessage sendMessage;

    @Autowired
    private RedisUtil redisUtil;
    @Autowired
    private UserMapper userMapper;


    @Override
    public Result sendVerifyCode(String email) {
        Result res = new Result();
        if (redisUtil.getExpire(email) > 0) {
            res.error(HttpCodeEnum.CODE_EXIST, "");
        } else {
            String verifyCode = generateVerifyCode();
//        设置验证码过期时间
            redisUtil.set(email, verifyCode, RegularConstant.CODE_EXPIRE_TIME);
            sendMessage.sendCommonMessage(email, "验证码", "您的验证码为：" + verifyCode + " ," + RegularConstant.CODE_EXPIRE_TIME / 60 + "分钟后过期");
            res.ok();
        }
        return res;
    }

    @Override
    public Result login(AuthVo auth) {
        LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(User::getUserName, auth.getUserName());
        User user = userMapper.selectOne(queryWrapper);
        UserVo userVo = BeanCopyUtils.copyBean(user, UserVo.class);
        Result result = new Result<>();
        if (Objects.nonNull(user) && BcryptUtil.matches(auth.getUserPassword(), user.getUserPassword())) {
//            设置token过期时间
            String token = getToken();
            redisUtil.setUserInfo(token, user, RegularConstant.TOKEN_EXPIRE_TIME);
//            返回响应数据
            HashMap<String, Object> mapVo = new HashMap<>();
            mapVo.put("token", token);
            mapVo.put("user", userVo);
            result.ok(mapVo);
//            result = Result.okResult(mapVo);
        } else {
            result.error(HttpCodeEnum.USERNAME_OR_PASSWORD_ERROR, "");
        }
        return result;
    }

    @Override
    public Result getNewToken(String token) {
        User user = redisUtil.getUserInfo(token);
//            删除原token
        redisUtil.delete(token);
        String newToken = getToken();
//            设置新token过期时间
        redisUtil.setUserInfo(newToken, user, RegularConstant.TOKEN_EXPIRE_TIME);
        HashMap<String, Object> map = new HashMap<>();
        map.put("token", newToken);
        Result result = new Result();
        return result.ok(map);
    }

    @Override
    public Result register(AuthVo auth) {
        Result res = new Result();
//        校验验证码
        if (verify(auth.getEmail(), auth.getCode())) {
            LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(User::getUserName, auth.getUserName());
            User user = userMapper.selectOne(queryWrapper);
//            用户名唯一性校验
            if (Objects.isNull(user)) {
                User newUser = new User();
                newUser.setUserName(auth.getUserName());
                newUser.setUserPassword(BcryptUtil.encode(auth.getUserPassword()));
                newUser.setEmail(auth.getEmail());
                userMapper.insert(newUser);
                res.ok();
            } else {
                res.error(HttpCodeEnum.USERNAME_EXIST,"");
            }
        } else {
            res.error(HttpCodeEnum.EMAIL_ERROR,"");
        }
        return res;
    }

    @Override
    public Result logout(String token) {
        redisUtil.delete(token);
        Result result = new Result();
        return result.ok();
    }


    private String generateVerifyCode() {
        // 实现验证码生成逻辑，比如生成6位随机数字
        Random random = new Random();
        return String.valueOf(random.nextInt(900000) + 100000); // 生成6位随机数字，范围是100000-999999
    }

    private String getToken() {
        return UUID.randomUUID().toString().replaceAll("-", "");
    }

    private boolean verify(String email, Integer code) {
        String verifyCode = redisUtil.get(email);
        return Objects.nonNull(verifyCode) && verifyCode.equals(String.valueOf(code));
    }
}
